using HossMvp.Core;
using HossMvp.WinForms;
using Sample.Models;
using System.Linq;

namespace Sample.Presenters
{
    public class PreferencesPresenter : AbstractPresenter
    {
        private string section;
        private bool preferencesModified;
        private AbstractModel model;

        private AbstractView view
        {
            get { return this.ViewManager.Views.Single(v => v.Name == "PreferencesView"); }
        }

        public PreferencesPresenter(AbstractModelManager modelManager, AbstractViewManager viewManager)
            : base(modelManager, viewManager, new WinFormsCommandProcessor(new NameDecorator("Preferences")))
        {
            this.RegisterCommands();
        }

        #region MyRegion

        private void RegisterCommands()
        {
            var decorator = this.CommandProcessor.Decorator;
            this.CommandProcessor.RegisterCommand(decorator.NameOf<PreferencesPresenter>(p => p.CloseOK)
                , this.CloseOK
                , () => true);
            this.CommandProcessor.RegisterCommand(decorator.NameOf<PreferencesPresenter>(p => p.CloseCancel)
                , this.CloseCancel
                , () => true);
            this.CommandProcessor.RegisterCommand(decorator.NameOf<PreferencesPresenter>(p => p.Apply)
                , this.Apply
                , () => this.preferencesModified);
            this.CommandProcessor.RegisterCommand(decorator.NameOf<PreferencesPresenter>(p => p.SelectSection)
                , this.SelectSection
                , () => true);
            this.CommandProcessor.RegisterCommand(decorator.NameOf<PreferencesPresenter>(p => p.SetPreferencesModified)
                , this.SetPreferencesModified
                , () => true);
        }

        private void CloseOK(CommandContext context)
        {
            var result = this.view.Action("GetPreferences")
                .WithArgument("section", this.section)
                .Execute();

            this.view.Action("ApplyPreferences")
                .WithArgument("section", this.section)
                .WithArguments(result.Data)
                .Execute();

            this.model.Action("SavePreferences")
                .WithArgument("section", this.section)
                .WithArguments(result.Data)
                .Execute();

            this.view.Action("Close").Execute();
            this.ViewManager.Remove(this.view);
        }

        private void CloseCancel(CommandContext context)
        {
            var result = this.model.Action("LoadPreferences")
                .WithArgument("section", this.section)
                .Execute();

            this.view.Action("ApplyPreferences")
                .WithArgument("section", this.section)
                .WithArguments(result.Data)
                .Execute();

            this.view.Action("Close").Execute();
            this.ViewManager.Remove(this.view);
        }

        private void Apply(CommandContext context)
        {
            var result = this.view.Action("GetPreferences")
                .WithArgument("section", this.section)
                .Execute();

            this.view.Action("ApplyPreferences")
                .WithArgument("section", this.section)
                .WithArguments(result.Data)
                .Execute();

            this.preferencesModified = false;
        }

        private void SelectSection(CommandContext context)
        {
            this.preferencesModified = false;

            var result = this.view.Action("SelectSection")
                .WithArgument("sender", ((WinFormsCommandContext)context).Sender)
                .Execute();
            this.section = result.Get<string>("selection");

            // load preferences section settings
            this.model = this.ModelManager.Create<PreferencesModel>("Preferences",
                new PreferencesModel.PreferencesContentProvider(new NameDecorator("Preferences")));

            var preferences = this.model.Action("LoadPreferences")
                .WithArgument("section", this.section)
                .Execute();

            // initialize the section
            this.view.Action("InitializeSection")
                .WithArgument("section", this.section)
                .WithArguments(preferences.Data)
                .Execute();
        }

        private void SetPreferencesModified(CommandContext context)
        {
            this.preferencesModified = true;
        }

        #endregion MyRegion
    }
}